using System;
using System.Collections.Generic;
using NHibernate;
using NHibernate.Criterion;
using Sesi.Dados.Entidades;
using Sesi.IRepositorio;
using Sesi.Dados.Enumeradores;

namespace Sesi.Repositorio
{
    public class RepositorioParticipante : IRepositorioParticipante
    {
        private void AtualizarSessao ()
        {
            //GerenciadorBD.Instance.SessaoAtual().Connection.Close();
            //GerenciadorBD.Instance.SessaoAtual().Refresh();
            //GerenciadorBD.Instance.SessaoAtual().Connection.Open();
        }

        public Participante Inserir(Participante participante)
        {
            GerenciadorBD.Instance.SessaoAtual().Save(participante);
            return participante;
        }

        public Participante Atualizar(Participante participante)
        {
            Participante tmpParticipante = ObterPorId(participante.ParticipantesId);

            tmpParticipante.ConfAbertura = participante.ConfAbertura;
            tmpParticipante.ConfEncerramento = participante.ConfEncerramento;
            tmpParticipante.Cpf = participante.Cpf;
            tmpParticipante.Email = participante.Email;
            tmpParticipante.Endereco = participante.Endereco;
            tmpParticipante.Instituicao = participante.Instituicao;
            tmpParticipante.MesaRedonda1 = participante.MesaRedonda1;
            tmpParticipante.MesaRedonda2 = participante.MesaRedonda2;
            tmpParticipante.Nome = participante.Nome; 
            tmpParticipante.Rg = participante.Rg;
            tmpParticipante.SalaTematica = participante.SalaTematica;
            tmpParticipante.Telefone = participante.Telefone;
            
            GerenciadorBD.Instance.SessaoAtual().Update(tmpParticipante);
            return tmpParticipante;
        }

        public void Excluir(Participante participante)
        {
            GerenciadorBD.Instance.SessaoAtual().Delete(participante);
        }

        public IList<Participante> ObterTodos()
        {
            AtualizarSessao();
            ICriteria criteria = GerenciadorBD.Instance.SessaoAtual().CreateCriteria(typeof(Participante))
                                .AddOrder(Order.Asc("Nome"));

            return criteria.List<Participante>() as List<Participante>;
        }

        public Participante ObterPorId(int id)
        {
            AtualizarSessao();
            return GerenciadorBD.Instance.SessaoAtual().Get<Participante>(id);
        }

        public IList<Participante> ObterTodosPorPalestra(Palestras palestra)
        {
            AtualizarSessao();
            ICriteria criteria = GerenciadorBD.Instance.SessaoAtual().CreateCriteria(typeof(Participante))
                               .Add(Restrictions.Or(Restrictions.Or(Restrictions.Eq("ConfAbertura", palestra), 
                               Restrictions.Eq("ConfEncerramento", palestra)), 
                               Restrictions.Or(Restrictions.Eq("SalaTematica", palestra), 
                               Restrictions.Or(Restrictions.Eq("MesaRedonda1", palestra), 
                               Restrictions.Eq("MesaRedonda2", palestra)))))
                               .AddOrder(Order.Asc("Nome"));

            return criteria.List<Participante>() as List<Participante>;
        }

        public int ObterQuantidadeTodosPorPalestra(Palestras palestra)
        {
            AtualizarSessao();
            ICriteria criteria = GerenciadorBD.Instance.SessaoAtual().CreateCriteria(typeof(Participante))
                               .Add(Restrictions.Or(Restrictions.Or(Restrictions.Eq("ConfAbertura", palestra),
                               Restrictions.Eq("ConfEncerramento", palestra)),
                               Restrictions.Or(Restrictions.Eq("SalaTematica", palestra),
                               Restrictions.Or(Restrictions.Eq("MesaRedonda1", palestra),
                               Restrictions.Eq("MesaRedonda2", palestra)))))
                               .SetProjection(Projections.Count("ParticipantesId"));

            return (int)criteria.UniqueResult();
        }

        public int QuantidadeParticipantesPorPalestra(Palestras palestra)
        {
            AtualizarSessao();
            ICriteria criteria = GerenciadorBD.Instance.SessaoAtual().CreateCriteria(typeof(Participante)).
                                //.CreateAlias("MesaRedonda1","MesaRedonda1").CreateAlias("MesaRedonda2","MesaRedonda2").
                                Add(Restrictions.Or(Restrictions.Eq("MesaRedonda1",palestra),Restrictions.Eq("MesaRedonda2",palestra)))
                                //.Add(Restrictions.Eq("TipoPalestra", tipoPalestra))
                                .SetProjection(Projections.Count("ParticipantesId"));
            

            return (int)criteria.UniqueResult();
        }

        public int ParticipantesPorSalaTematica(Palestras salatematica)
        {
            ICriteria criteria = GerenciadorBD.Instance.SessaoAtual().CreateCriteria(typeof(Participante))
                                .Add(Restrictions.Eq("SalaTematica", salatematica))
                                .SetProjection(Projections.Count("ParticipantesId"));


            return (int)criteria.UniqueResult();
        }

        public int ParticipantesPorConfAbertura(Palestras confAbertura)
        {
            ICriteria criteria = GerenciadorBD.Instance.SessaoAtual().CreateCriteria(typeof(Participante))
                                .Add(Restrictions.Eq("ConfAbertura", confAbertura))
                                .SetProjection(Projections.Count("ParticipantesId"));


            return (int)criteria.UniqueResult();
        }

        public int ParticipantesPorConfEncerramento(Palestras confEncerramento)
        {
            ICriteria criteria = GerenciadorBD.Instance.SessaoAtual().CreateCriteria(typeof(Participante))
                               .Add(Restrictions.Eq("ConfEncerramento", confEncerramento))
                               .SetProjection(Projections.Count("ParticipantesId"));


            return (int)criteria.UniqueResult();
        }

        public int ParticipantesPorMesaRedonda(Palestras mesaRedonda)
        {
            ICriteria criteria = GerenciadorBD.Instance.SessaoAtual().CreateCriteria(typeof(Participante))
                                .Add( Restrictions.Or(Restrictions.Eq("MesaRedonda1", mesaRedonda),Restrictions.Eq("MesaRedonda2", mesaRedonda)))
                                .SetProjection(Projections.Count("ParticipantesId"));

            return (int)criteria.UniqueResult();
        }

        public IList<Participante> ObterParticipantesPorSalaTematica(Palestras salatematica)
        {
            ICriteria criteria = GerenciadorBD.Instance.SessaoAtual().CreateCriteria(typeof (Participante))
                .Add(Restrictions.Eq("SalaTematica", salatematica));

            return criteria.List<Participante>() as List<Participante>;
        }

        public IList<Participante> ObterParticipantesPorConfAbertura(Palestras confAbertura)
        {
            ICriteria criteria = GerenciadorBD.Instance.SessaoAtual().CreateCriteria(typeof (Participante))
                .Add(Restrictions.Eq("ConfAbertura", confAbertura));

            return criteria.List<Participante>() as List<Participante>;
        }

        public IList<Participante> ObterParticipantesPorConfEncerramento(Palestras confEncerramento)
        {
            ICriteria criteria = GerenciadorBD.Instance.SessaoAtual().CreateCriteria(typeof (Participante))
                .Add(Restrictions.Eq("ConfEncerramento", confEncerramento));

            return criteria.List<Participante>() as List<Participante>;
        }

        public IList<Participante> ObterParticipantesPorMesaRedonda(Palestras mesaRedonda)
        {
            ICriteria criteria = GerenciadorBD.Instance.SessaoAtual().CreateCriteria(typeof (Participante))
                .Add(Restrictions.Or(Restrictions.Eq("MesaRedonda1", mesaRedonda),
                                     Restrictions.Eq("MesaRedonda2", mesaRedonda)));

            return criteria.List<Participante>() as List<Participante>;
        }
    }
}